﻿using UnityEngine;
using Zero;

/// <summary>
/// 元素反应：超载
/// </summary>
public class ElementOverloaded : IElementReaction
{
    private const float Radius = 5f;

    private readonly IElementHolder _holder;
    private readonly Collider[] _cache = new Collider[100];

    public ElementOverloaded(IElementHolder holder)
    {
        _holder = holder;
    }

    public void Reaction(TriggerElementData triggerElementData)
    {
        if (triggerElementData.ElementType == ElementType.Electric)
        {
            var fireAura = _holder.GetGeneralElementAura(ElementType.Fire);
            if (fireAura.Gauge > 0f)
            {
                var cost = triggerElementData.Gauge;
                triggerElementData.Gauge -= fireAura.Gauge;
                fireAura.UseGauge(cost);
                triggerElementData.IsTriggered = true;
                CreateExplosion();
                ServiceLocator.Get<IWorldNumberService>()
                    .CreateElementReaction(_holder.Owner.transform.position, "超载");
                return;
            }
        }

        if (triggerElementData.ElementType == ElementType.Fire)
        {
            var electricAura = _holder.GetGeneralElementAura(ElementType.Electric);
            if (electricAura.Gauge > 0f)
            {
                var cost = triggerElementData.Gauge;
                triggerElementData.Gauge -= electricAura.Gauge;
                electricAura.UseGauge(cost);
                triggerElementData.IsTriggered = true;
                CreateExplosion();
                ServiceLocator.Get<IWorldNumberService>()
                    .CreateElementReaction(_holder.Owner.transform.position, "超载");
            }
        }
    }

    private void CreateExplosion()
    {
        var count = Physics.OverlapSphereNonAlloc(_holder.Owner.transform.position, Radius,
            _cache);
        for (int i = 0; i < count; i++)
        {
            if (!_cache[i].CompareTag(_holder.Owner.tag))
            {
                continue;
            }

            if (_cache[i].TryGetComponent(out ActorDamageable damageable))
            {
                var attackData = new AttackData
                {
                    Damage = 100f,
                    Source = _holder.Owner,
                    ElementType = ElementType.Fire,
                    ElementGauge = 0f,
                    StrikeType = StrikeType.Blunt
                };
                damageable.TakeDamage(attackData);
            }
        }
    }
}